package com.tsugun.mediaplayer.view.widget;

import android.content.Context;
import android.support.v4.view.animation.FastOutSlowInInterpolator;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;

import static com.tsugun.mediaplayer.presenter.utils.LogHelper.*;

/**
 * 锁屏布局
 * Created by shize on 2017/8/4.
 */

public class SlidingLayout extends FrameLayout implements GestureDetector.OnGestureListener {

    private static final int V_CLOSE = 2000; // 最低解锁手速
    private static final long TIME_ANIMATION = 300; // 动画时间

    private static int mScreenHeight; // 屏幕高度
    private static int mScreenWidth; // 屏幕宽度

    private GestureDetector mGestureDetector; // 手势辅助类
    private ScreenMoveEventListener mScreenMoveEventListener; // 滑动事件监听
    private int mPosL; // Y轴位置
    private int mPosT; // X轴位置
    private int mPosR; // R轴位置
    private int mPosB; // B轴位置
    private boolean isOpen; // 是否保持界面开启

    private boolean isIntercept; // 是否拦截

    public SlidingLayout(Context context) {
        this(context, null);
    }

    public SlidingLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public SlidingLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mGestureDetector = new GestureDetector(context, this);
        isOpen = true;
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);
        mPosL = l;
        mPosT = t;
        mPosR = r;
        mPosB = b;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mScreenHeight = MeasureSpec.getSize(heightMeasureSpec);
        mScreenWidth = MeasureSpec.getSize(widthMeasureSpec);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            checkView();
            setState();
        }
        mGestureDetector.onTouchEvent(event);
        return isIntercept;
    }

    /**
     * 检测是否解锁
     */
    private void checkView() {
        isOpen = mPosL <= (mScreenWidth / 3);
        Log.d(INSTANCE.getTAG(), "onTouchEvent: posL=" + mPosL + " isOpen=" + isOpen);
    }

    /**
     * 设置控件开关状态
     */
    private void setState() {
        if (!isOpen) {
            close();
        } else {
            open();
        }
    }

    /**
     * 关闭
     */
    private void close() {
        isOpen = false;
        doAnimation(mPosL, mScreenWidth);
    }

    /**
     * 不关闭
     */
    private void open() {
        isOpen = true;
        doAnimation(mPosL, 0);
    }

    /**
     * 滑动屏幕
     *
     * @param d 滑动距离
     */
    private void scroll(int d) {
        if (mPosL + d < 0) {
            layout(0, 0, mScreenWidth, mScreenHeight);
        } else {
            layout(mPosL + d, mPosT, mPosR + d, mPosB);
        }
        if (mScreenMoveEventListener != null) {
            mScreenMoveEventListener.onScroll(d);
        }
    }

    /**
     * 动画
     *
     * @param nowX    当前X轴的位置
     * @param targetX 目标X轴的位置
     */
    private void doAnimation(int nowX, final int targetX) {
        TranslateAnimation animation = new TranslateAnimation(0, targetX - nowX, 0, 0);
        // 计算得出还有多少距离需要移动，以保持不管还剩多少距离都能以同意速度移动
        animation.setDuration(TIME_ANIMATION * Math.abs(targetX - nowX) / mScreenWidth);
        // 动画插值器
        animation.setInterpolator(new FastOutSlowInInterpolator());
        // 动画播放监听器
        animation.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {

            }

            @Override
            public void onAnimationEnd(Animation animation) {
                // 先清除未播放完成的动画
                clearAnimation();
                layout(targetX, 0, targetX + mScreenWidth, mScreenHeight);
                // 设置状态回调
                setCallback();
            }

            @Override
            public void onAnimationRepeat(Animation animation) {

            }
        });
        startAnimation(animation);
    }

    // 是否启动拦截
    public void isIntercept(boolean isIntercept){
        this.isIntercept = isIntercept;
    }

    /**
     * 设置状态回调
     */
    private void setCallback() {
        if (mScreenMoveEventListener == null) {
            return;
        }
        if (isOpen) {
            mScreenMoveEventListener.onOpen();
        } else {
            mScreenMoveEventListener.onClose();
        }
    }

    @Override
    public boolean onDown(MotionEvent e) {
        Log.d(INSTANCE.getTAG(), "onDown: ");
        return true;
    }

    @Override
    public void onShowPress(MotionEvent e) {
        Log.d(INSTANCE.getTAG(), "onShowPress: ");
    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        Log.d(INSTANCE.getTAG(), "onSingleTapUp: ");
        return false;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        int d = (int) (e2.getX() - e1.getX());
        scroll(d);
        return false;
    }

    @Override
    public void onLongPress(MotionEvent e) {
        Log.d(INSTANCE.getTAG(), "onLongPress: ");
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        Log.d(INSTANCE.getTAG(), "onFling: vX=" + velocityX);
        if (velocityX > V_CLOSE && (e2.getX() > e1.getX())) {
            close();
        }
        return false;
    }

    /**
     * 设置滑动时间监听器
     */
    public void setScreenMoveEvent(ScreenMoveEventListener e) {
        mScreenMoveEventListener = e;
    }

    /**
     * 滑动事件监听
     */
    public interface ScreenMoveEventListener {
        /**
         * 滑动时
         *
         * @param distance 滑动距离
         */
        void onScroll(int distance);

        /**
         * 判断开启
         */
        void onOpen();

        /**
         * 判读关闭
         */
        void onClose();
    }
}
